home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 4
/
Apprentice-Release4.iso
/
Source Code
/
C
/
Frameworks
/
Extension Shell 1.4
/
Extension Shell 1.4 (Source)
/
ShowIcon.c
< prev
next >
Wrap
Text File
|
1995-11-01
|
8KB
|
327 lines
/* NAME:
ShowIcon.c
WRITTEN BY:
Dair Grant, based on Peter Lewis/Jim Walker/François Pottier/previous
ShowINIT authors' work.
DESCRIPTION:
This code is based on various bits of icon drawing code, and
adapted to support animated icons.
NOTES:
We use the System 7 IconSuite calls to display the appropriate icon
from our INIT code's icon family. This looks after bit depths, and
removes the need for 'cicn's for colour displays.
If we're not running under System 7, we can only handle 'ICN#'
resources.
___________________________________________________________________________
*/
//=============================================================================
// Include files
//-----------------------------------------------------------------------------
#include <Icons.h>
#include "ES.h"
#include "ShowIcon.h"
//=============================================================================
// Private function prototypes
//-----------------------------------------------------------------------------
unsigned short CheckSum(unsigned short x);
void GetIconRect(Rect *theRect, Rect *thePortRect);
void NextPosition(Rect *theRect);
void PlotBWIcon(Rect *iconRect, Handle theIcon);
//=============================================================================
// Private defines
//-----------------------------------------------------------------------------
#define LMVCoord (* (short*) 0x92A) // Vertical coordinate
#define LMVCheckSum (* (short*) 0x928) // Vertical coordinate checksum
#define LMHCoord (* (short*) 0x92C) // Horizontal coordinate
#define LMHCheckSum (* (short*) 0x92E) // Horizontal coordinate checksum
//=============================================================================
// PlotINITIcon : Plot a series of icons on the screen.
//-----------------------------------------------------------------------------
// Note : We are passed an array of icon resource IDs, the number of
// valid IDs there are in the array, the number of ticks to wait
// between showing each icon, and a status flag for the presence
// of System 7.
//
// Usually Extensions will pass in only one icon, but this allows
// us to support animated icons as well.
//
// We use System 7's IconSuite routines to plot the icons. These
// look after all the details of deciding what icon to use,
// depending on the depth of the display. They also work using
// the same icon families that the Finder uses, which means
// there's no need for a 'cicn' version.
//
// If we don't have System 7, we don't have access to the
// IconSuite routines, and so have to resort to plotting 'ICN#'
// resources.
//-----------------------------------------------------------------------------
void PlotINITIcon(Boolean haveSys7, short animDelay, short numIcons, short (*theIcons)[])
{ CGrafPtr oldPort;
CGrafPort newPort;
Handle theIconHnds[kMaxNumIcons+1];
Rect theIconPos;
long theTicks;
short i;
// Save the port, and open a new one
GetPort((GrafPtr *) &oldPort);
OpenCPort(&newPort);
SetPort((GrafPort *) &newPort);
// Work out where we should draw the icon
GetIconRect(&theIconPos, &newPort.portRect);
// Read in handles to as many icons as we have to/can. If we Get/Plot/Dispose
// of each icon in turn, we can get jerky animation.
for (i = 1; i <= numIcons && i <= kMaxNumIcons; i++)
{
if (haveSys7)
GetIconSuite(&theIconHnds[i], (*theIcons)[i], svAllLargeData);
else
theIconHnds[i] = GetResource('ICN#', (*theIcons)[i]);
}
// Plot all the icons, with the right delay
for (i = 1; i <= numIcons && i <= kMaxNumIcons; i++)
{
if (haveSys7)
PlotIconSuite(&theIconPos, atNone, ttNone, theIconHnds[i]);
else
PlotBWIcon(&theIconPos, theIconHnds[i]);
Delay(animDelay, &theTicks);
}
// Before releasing them again
for (i = 1; i <= numIcons && i <= kMaxNumIcons; i++)
{
if (haveSys7)
DisposeIconSuite(theIconHnds[i], true);
else
ReleaseResource(theIconHnds[i]);
}
// Set things up for the next INIT's icon - if we drew anything
if (numIcons > 0)
NextPosition(&theIconPos);
// Dispose of our temporary port, and restore the old one
CloseCPort(&newPort);
SetPort((GrafPtr) oldPort);
}
//=============================================================================
// CheckSum : Verify that the previous INIT knew about ShowINIT Icon.
//-----------------------------------------------------------------------------
unsigned short CheckSum(unsigned short x)
{
return((x << 1) | (x >> 15)) ^ 0x1021;
}
//=============================================================================
// GetIconRect : Calculate the correct position for our INIT's icon.
//-----------------------------------------------------------------------------
// Note : We leave the correct position in theRect. We are given the
// portRect field of the current graphics port in thePortRect.
//
// *theRect is forced to be onscreen. This is done by taking
// the horizontal offset modulo the screen width to generate the
// horizontal position of the icon, and the offset divided by the
// screen width to generate the proper row. This mechanism can get
// messed up if people plot icons at non-standard offsets.
//
// We are also responsible for initialising the ShowInitIcon
// mechanism if we're the first INIT to load.
//-----------------------------------------------------------------------------
void GetIconRect(Rect *theRect, Rect *thePortRect)
{
// If we're first, initialise the mechanism for everyone else
if (CheckSum(LMHCoord) != LMHCheckSum)
LMHCoord = 8;
if (CheckSum(LMVCoord) != LMVCheckSum)
LMVCoord = thePortRect->bottom - 40;
// Wrap round if we would move off the edge of the screen
if (LMHCoord + 34 > thePortRect->right)
{
theRect->left = 8;
theRect->top = LMVCoord - 40;
}
// Otherwise move ourselves to the next position
else
{
theRect->left = LMHCoord;
theRect->top = LMVCoord;
}
theRect->right = theRect->left + 32;
theRect->bottom = theRect->top + 32;
}
//=============================================================================
// NextPosition : Advance the ShowIcon position for the next INIT.
//-----------------------------------------------------------------------------
void NextPosition(Rect *theRect)
{
// Update the position for the next INIT
LMHCoord = theRect->left + 40;
LMVCoord = theRect->top;
LMHCheckSum = CheckSum(LMHCoord);
LMVCheckSum = CheckSum(LMVCoord);
}
//=============================================================================
// PlotBWIcon : Plot an 'ICN#' icon.
//-----------------------------------------------------------------------------
void PlotBWIcon(Rect *iconRect, Handle theIcon)
{ BitMap src;
GrafPtr thePort;
// Lock the icon down, if we have one
if (theIcon == nil)
return;
else
HLock(theIcon);
// Prepare the source and destination bitmaps.
src.baseAddr = *theIcon + 128; // Offset to Mask.
src.rowBytes = 4;
SetRect(&src.bounds, 0, 0, 32, 32);
GetPort(&thePort);
// Transfer the mask.
CopyBits(&src, &thePort->portBits, &src.bounds, iconRect, srcBic, nil);
// Followed by the icon.
src.baseAddr = *theIcon; /// 0 offset to icon data.
CopyBits(&src, &thePort->portBits, &src.bounds, iconRect, srcOr, nil);
// Unlock the icon.
HUnlock(theIcon);
}